// 版权所有2016 etcd作者
// 
// 根据Apache许可证2.0版（以下简称“许可证”）获得许可；
// 除非遵守许可证，否则不得使用此文件。
// 您可以通过
// 
// www.apache.org/licenses/LICENSE-2.0 
// 
// 除非适用法律要求或书面同意，否则根据许可证分发的软件
// 按“原样”分发，
// 无任何明示或暗示的保证或条件。
// 请参阅许可证，了解管理许可的特定语言和
// 许可证下的限制。

// go:构建linux 
// +构建linux 

package fileutil

import (
	"os"
	"syscall"
)

func preallocExtend(f *os.File, sizeInBytes int64) error {
	// 使用mode=0更改大小
	err := syscall.Fallocate(int(f.Fd()), 0, 0, sizeInBytes)
	if err != nil {
		errno, ok := err.(syscall.Errno)
		// 不受支持；回退
		// 在某些环境中频繁中止EINTR；回退
		if ok && (errno == syscall.ENOTSUP || errno == syscall.EINTR) {
			return preallocExtendTrunc(f, sizeInBytes)
		}
	}
	return err
}

func preallocFixed(f *os.File, sizeInBytes int64) error {
	// 使用mode=1保持大小；请参阅FALLOC_FL_KEEP_SIZE 
	err := syscall.Fallocate(int(f.Fd()), 1, 0, sizeInBytes)
	if err != nil {
		errno, ok := err.(syscall.Errno)
		// 将不支持视为零错误
		if ok && errno == syscall.ENOTSUP {
			return nil
		}
	}
	return err
}
